/**
 *
 */
package com.angel.data.generator.comparators;

import java.util.Comparator;

import org.apache.log4j.Logger;

import com.angel.data.generator.exceptions.DataGeneratorException;
import com.angel.data.generator.interfaces.DataGenerator;

/**
 *
 * @author William
 * @since 23/April/2009
 *
 */
public class DataGeneratorDependencesAscComparator implements Comparator<DataGenerator>{

	private static final Logger LOGGER = Logger.getLogger(DataGeneratorDependencesAscComparator.class);

	public int compare(DataGenerator o1, DataGenerator o2) {
		/*
		Returns:
			a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
		*/
		int result = 0;
		if(o1.getClass().getCanonicalName().equals(o2.getClass().getCanonicalName())){
			result = 0;
			return result;
		}

		boolean _1dependsOn2 = this.dependsOn(o1, o2);

		boolean _2dependsOn1 = this.dependsOn(o2, o1);

		if(_1dependsOn2 && _2dependsOn1 ){
			String errorMessage = "Cycle dependence between [" + o2.getClass().getSimpleName() + "] and [" + o1.getClass().getSimpleName() + "].";
			LOGGER.error(errorMessage);
			throw new DataGeneratorException(errorMessage);
		} else {
			if(_1dependsOn2){
				LOGGER.info(o1.getClass().getSimpleName() + " depends on " + o2.getClass().getSimpleName());
				result = 1;
			} else {
				if(_2dependsOn1){
					LOGGER.info(o2.getClass().getSimpleName() + " depends on " + o1.getClass().getSimpleName());
					result = -1;
				} else {
					LOGGER.info(o2.getClass().getSimpleName() + " independent " + o1.getClass().getSimpleName());
					result = -1;
				}
			}
		}

		return result;
	}

	/** Test if data generator depends on other data generator. This test is realized with the other deta generator's dependencies.
	 * If data generator is in other data generator's dependencies, it return true. Otherwise it returns false.
	 *
	 * @param dataGenerator to test if it depends on other data generator.
	 * @param otherDataGenerator to test if it should be execute before data generator.
	 * @return true if data generator depends on other data generator dependencies. Otherwise it returns false.
	 */
	private boolean dependsOn(DataGenerator dataGenerator, DataGenerator otherDataGenerator) {
		Class<? extends DataGenerator>[] dependencesOf = dataGenerator.getDependecesGenerators();
		boolean dependsOn = false;
		if(dependencesOf != null && dependencesOf.length > 0){
			for(Class<? extends DataGenerator> dataGeneratorClass : dependencesOf){
				if(otherDataGenerator.getClass().getCanonicalName().equals(dataGeneratorClass.getCanonicalName())){
					dependsOn = true;
					break;
				}
			}
		}
		return dependsOn;
	}
}
